package com.ruoyi.common.dingtalk.template;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.lgc.pojo.properties.DingtalkSettingProperties;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.*;
import com.ruoyi.common.dingtalk.pojo.constant.DingtalkConstant;
import com.ruoyi.common.dingtalk.pojo.dto.ClassDto;
import com.ruoyi.common.dingtalk.pojo.dto.GroupDto;
import com.taobao.api.ApiException;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 钉钉模板
 *
 * @author 陈立高
 * @date 2024/03/25
 */
public class DingtalkTemplate {
    private DingtalkSettingProperties dingtalkSettingProperties;

    public DingtalkTemplate(DingtalkSettingProperties dingtalkSettingProperties) {
        this.dingtalkSettingProperties = dingtalkSettingProperties;
    }

    /**
     * 获取访问令牌
     *
     * @return {@link String}
     * @throws ApiException api例外
     */
    public String getAccessToken() throws ApiException {
        //获取access_token
        String url = dingtalkSettingProperties.getAccessTokenUrl(); // 钉钉API url
        DingTalkClient client = new DefaultDingTalkClient(url);
        OapiGettokenRequest req = new OapiGettokenRequest();
        req.setHttpMethod(DingtalkConstant.REQUEST_METHOD_GET.getStr());
        OapiGettokenResponse rsp = client.execute(req);
        JSONObject resultObj = JSONUtil.parseObj(JSONUtil.toJsonStr(rsp.getBody()));
        if (!(DingtalkConstant.RESPONSE_CODE_SUCCESS.getStr().equals(resultObj.get("errmsg")))) {
            throw new RuntimeException("获取钉钉access_token失败");
        }
        return resultObj.getStr(DingtalkConstant.ACCESS_TOKEN_KEY.getStr());
    }

    /**
     * 获取所有的考勤组和考勤班次
     *
     * @return {@link List}<{@link GroupDto}>
     * @throws ApiException api例外
     */
    public List<GroupDto> loadAttendanceSchedule() throws ApiException {
        //获取考勤组和考勤班次
        String attendanceScheduleUrl = dingtalkSettingProperties.getAttendanceScheduleUrl();
        String accessToken = getAccessToken();
        DingTalkClient client = new DefaultDingTalkClient(String.format(attendanceScheduleUrl, accessToken));
        OapiAttendanceGetsimplegroupsRequest req = new OapiAttendanceGetsimplegroupsRequest();
        OapiAttendanceGetsimplegroupsResponse rsp = client.execute(req);
        JSONObject resultObj = JSONUtil.parseObj(JSONUtil.toJsonStr(rsp.getBody()));
        //获取所有考勤组
        JSONArray JsonGroups = JSONUtil.parseObj(JSONUtil.toJsonStr(rsp.getBody())).getJSONObject("result").getJSONArray("groups");
        return JsonGroups.stream().map(g -> {
            GroupDto groupDto = new GroupDto();
            JSONObject group = JSONUtil.parseObj(g);
            groupDto.setGroupId(group.getLong("group_id"));
            groupDto.setGroupName(group.getStr("group_name"));
            List<ClassDto> collect = group.getJSONArray("selected_class").stream().map(c -> {
                JSONObject jsonObject = JSONUtil.parseObj(c);
                ClassDto classDto = new ClassDto();
                classDto.setClassId(jsonObject.getLong("class_id"));
                classDto.setClassName(jsonObject.getStr("class_name"));
                return classDto;
            }).collect(Collectors.toList());
            groupDto.setClassList(collect);
            groupDto.setDingTalkSetting(JSONUtil.toJsonStr(g));
            return groupDto;
        }).collect(Collectors.toList());
    }

    /**
     * 获取考勤成员列表
     *
     * @param groupId 组id
     * @return {@link List}<{@link String}>
     * @throws ApiException api例外
     */
    public List<String> memberList(Long groupId) throws ApiException {
        //获取排班的老师
        String groupMemberUrl = dingtalkSettingProperties.getGroupMemberUrl();
        String accessToken = getAccessToken();
        DingTalkClient client = new DefaultDingTalkClient(String.format(groupMemberUrl, accessToken));
        OapiAttendanceGroupMemberListRequest req = new OapiAttendanceGroupMemberListRequest();
        req.setGroupId(groupId);
        req.setOpUserId(dingtalkSettingProperties.getOpUserId());
        OapiAttendanceGroupMemberListResponse rsp = client.execute(req, "");
        JSONObject resultObj = JSONUtil.parseObj(JSONUtil.toJsonStr(rsp.getBody()));
        if( resultObj.getJSONObject("result").getInt("cursor").equals(0)){
            return null;
        }
        return resultObj.getJSONObject("result").getJSONArray("result").stream().map(m -> {
            JSONObject jsonObject = JSONUtil.parseObj(m);
            return jsonObject.getStr("member_id");
        }).collect(Collectors.toList());
    }

    /**
     * 增加考勤人员
     *
     * @param memberList 成员列表
     */
    public void attendancePersonnelAdded(List<String> memberList, Long groupId) throws ApiException {
        //考勤人员添加
        String accessToken = getAccessToken();
        DingTalkClient client = new DefaultDingTalkClient(dingtalkSettingProperties.getGroupMemberUpdateUrl());
        OapiAttendanceGroupMemberUpdateRequest req = new OapiAttendanceGroupMemberUpdateRequest();
        req.setOpUserId(dingtalkSettingProperties.getOpUserId());
        req.setGroupId(groupId);
        req.setScheduleFlag(0L);
        OapiAttendanceGroupMemberUpdateRequest.TopGroupMemberUpdateParam obj1 = new OapiAttendanceGroupMemberUpdateRequest.TopGroupMemberUpdateParam();
        obj1.setAddUsers(memberList);
        req.setUpdateParam(obj1);
        OapiAttendanceGroupMemberUpdateResponse rsp = client.execute(req, accessToken);
        JSONObject resultObj = JSONUtil.parseObj(JSONUtil.toJsonStr(rsp.getBody()));
        if (!(DingtalkConstant.RESPONSE_CODE_SUCCESS.getStr().equals(resultObj.get("errmsg")))) {
            throw new RuntimeException("考勤员工添加失败");
        }
    }

    /**
     * 组织安排
     *
     * @param groupId  组id
     * @param classId  类id
     * @param workDate 工作日期
     * @param userIds  用户id
     * @throws ApiException api例外
     */
    public void groupSchedule(Long groupId, Long classId, Long workDate, List<String> userIds) throws ApiException {
        String accessToken = getAccessToken();
        DingTalkClient client = new DefaultDingTalkClient(dingtalkSettingProperties.getGroupScheduleAsync());
        OapiAttendanceGroupScheduleAsyncRequest req = new OapiAttendanceGroupScheduleAsyncRequest();
        req.setOpUserId(dingtalkSettingProperties.getOpUserId());
        req.setGroupId(groupId);
        //添加考勤人员
        List<OapiAttendanceGroupScheduleAsyncRequest.TopScheduleParam> collect = userIds.stream().map(u -> {
            OapiAttendanceGroupScheduleAsyncRequest.TopScheduleParam obj2 = new OapiAttendanceGroupScheduleAsyncRequest.TopScheduleParam();
            obj2.setShiftId(classId);
            obj2.setWorkDate(workDate);
            obj2.setIsRest(false);
            obj2.setUserid(u);
            return obj2;
        }).collect(Collectors.toList());
        req.setSchedules(collect);
        OapiAttendanceGroupScheduleAsyncResponse rsp = client.execute(req, accessToken);
        JSONObject resultObj = JSONUtil.parseObj(JSONUtil.toJsonStr(rsp.getBody()));
        if (!(DingtalkConstant.RESPONSE_CODE_SUCCESS.getStr().equals(resultObj.get("errmsg")))) {
            throw new RuntimeException("考勤排班失败");
        }
    }
}
